package logic

import (
	"fmt"
	"news/dao/mysql"
	"news/dao/redis"
	"news/models"
	"news/pkg/snowflake"
	"time"

	"go.uber.org/zap"
)

//帖子部份
// 创建帖子
func CreatePost(p *models.Post) (err error) {
	p.PostID = (snowflake.GenID())
	err = mysql.CreateInsertPost(p)
	if err != nil {
		return err
	}
	err = redis.CreateInsertPost(p.PostID, p.CommunityID)
	return
}

// 帖子列表
func GetCommunityInfo() (data []*models.CommunityPost, err error) {
	catlist, err := mysql.GetCommunityInfo()
	data = make([]*models.CommunityPost, 0, len(catlist))
	for _, post := range catlist {
		//获取帖子的信息
		list, _ := mysql.GetPostInfoList(post.CommunityID)
		for _, v := range list {
			// 获取作者名称
			user, err := mysql.GetUserByID(v.AuthorId)
			if err != nil {
				zap.L().Error("mysql.GetUserByID() failed",
					zap.String("author_id", fmt.Sprint(v.AuthorId)),
					zap.Error(err))
				continue
			}
			v.AuthorName = user.Username
			community, err := mysql.GetCommunityByPostID(v.CommunityID)
			if err != nil {
				zap.L().Error("mysql.GetCommunityByPostID() failed",
					zap.String("author_id", fmt.Sprint(v.CommunityID)),
					zap.Error(err))
				continue
			}
			v.CommunityName = community.CommunityName
			if v.CommunityID == post.CommunityID {
				post.Child = append(post.Child, &models.PostCommunity{
					PostID:        v.PostID,
					Title:         v.Title,
					Content:       v.Content,
					AuthorId:      v.AuthorId,
					AuthorName:    v.AuthorName,
					CommunityName: v.CommunityName,
					Status:        v.Status,
					CreateTime:    time.Time{},
				})
			}
		}
		data = append(data, post)
	}
	return
}

//根据ID 获取帖子详情
func GetPostById(pid int64) (data *models.ApiPostDetail, err error) {
	post, err := mysql.GetPostById(pid)
	if err != nil {
		zap.L().Error("mysql.GetPostById(pid) failed",
			zap.Int64("pid", pid), zap.Error(err))
		return
	}
	user, err := mysql.GetUserByID(post.AuthorId)
	if err != nil {
		zap.L().Error("mysql.GetUserByID(post.AuthorId) failed",
			zap.Int64("authorID", post.AuthorId), zap.Error(err))
		return
	}
	community, err := mysql.GetCommunityByPostID(post.CommunityID)
	if err != nil {
		zap.L().Error("mysql.GetCommunityByPostID(post.Post.CommunityID) failed",
			zap.Error(err))
		return
	}
	data = &models.ApiPostDetail{
		AuthorName: user.Username,
		Post:       post,
		Community:  community,
	}
	return
}

// 获取所有帖子的信息
func GetPostAll(p *models.Post, page, size int64) (dataInfo []*models.ApiPostDetail, err error) {
	dataAll, err := mysql.GetPostAll(p, page, size)
	if err != nil {
		zap.L().Error("mysql.GetPostAll(p) failed", zap.Error(err))
		return
	}
	dataInfo = make([]*models.ApiPostDetail, 0, len(dataAll)) // data 初始化
	for _, post := range dataAll {
		user, err := mysql.GetUserByID(post.AuthorId)
		if err != nil {
			zap.L().Error("mysql.GetUserByID(post.AuthorId) failed",
				zap.Int64("authorID", post.AuthorId), zap.Error(err))
			continue
		}
		community, err := mysql.GetCommunityByPostID(post.CommunityID)
		if err != nil {
			zap.L().Error("mysql.GetCommunityByPostID(post.CommunityID) failed",
				zap.Error(err))
			continue
		}
		postDetail := &models.ApiPostDetail{
			AuthorName: user.Username,
			Post:       post,
			Community:  community,
		}
		dataInfo = append(dataInfo, postDetail)
	}
	return
}

// 去redis 查询数据 按时间 或分数 查询
func GetPostListRedis(p *models.ParamPostIndexListForm) (dataInfo []*models.ApiPostDetail, err error) {
	ids, err := redis.GetPostIdsInOrder(p)
	if len(ids) == 0 {
		zap.L().Warn("redis.GetPostIdsInOrder return 0 data")
		return
	}
	if err != nil {
		zap.L().Error("redis.GetPostIdsInOrder failed",
			zap.String("ids", fmt.Sprintf("%s", ids)), zap.Error(err))
		return
	}

	posts, err := mysql.GetPostListByIds(ids)
	if err != nil {
		return
	}
	voteData, err := redis.GetPostVoteData(ids)
	if err != nil {
		return
	}
	dataInfo = make([]*models.ApiPostDetail, 0, len(posts))
	for idx, post := range posts {
		user, err := mysql.GetUserByID(post.AuthorId)
		if err != nil {
			zap.L().Error("mysql.GetUserByID(post.AuthorId) failed",
				zap.Int64("authorID", post.AuthorId), zap.Error(err))
			continue
		}
		community, err := mysql.GetCommunityByPostID(post.CommunityID)
		if err != nil {
			zap.L().Error("mysql.GetCommunityByPostID(post.CommunityID) failed",
				zap.Error(err))
			continue
		}
		postDetail := &models.ApiPostDetail{
			AuthorName: user.Username,
			VoteNum:    voteData[idx],
			Post:       post,
			Community:  community,
		}
		dataInfo = append(dataInfo, postDetail)
	}
	return
}

// 通过社区id 查询到对应的帖子内容
func GetCommunityPostListRedis(p *models.ParamPostIndexListForm) (dataInfo []*models.ApiPostDetail, err error) {
	// 2、去redis查询id列表
	ids, err := redis.GetCommunityPostIDsInOrder(p)
	if len(ids) == 0 {
		zap.L().Warn("redis.GetCommunityPostList(p) return 0 data")
		return
	}
	if err != nil {
		zap.L().Error("redis.GetCommunityPostIDsInOrderfailed",
			zap.Any("ids", ids), zap.Error(err))
		return
	}

	posts, err := mysql.GetPostListByIds(ids)
	if err != nil {
		return
	}
	voteData, err := redis.GetPostVoteData(ids)
	if err != nil {
		return
	}
	dataInfo = make([]*models.ApiPostDetail, 0, len(posts))
	for idx, post := range posts {
		user, err := mysql.GetUserByID(post.AuthorId)
		if err != nil {
			zap.L().Error("mysql.GetUserByID(post.AuthorId) failed",
				zap.Int64("authorID", post.AuthorId), zap.Error(err))
			continue
		}
		community, err := mysql.GetCommunityByPostID(post.CommunityID)
		if err != nil {
			zap.L().Error("mysql.GetCommunityByPostID(post.CommunityID) failed",
				zap.Error(err))
			continue
		}
		postDetail := &models.ApiPostDetail{
			AuthorName: user.Username,
			VoteNum:    voteData[idx],
			Post:       post,
			Community:  community,
		}
		dataInfo = append(dataInfo, postDetail)
	}
	return
}

// GetPostListNew
// 查询对帖子按时间或分数的展示，如果社区id 不为空的 就按社区id展示帖子
func GetPostListNew(p *models.ParamPostIndexListForm) (dataInfo []*models.ApiPostDetail, err error) {
	if p.CommunityID == 0 {
		dataInfo, err = GetPostListRedis(p)
	} else {
		dataInfo, err = GetCommunityPostListRedis(p)
	}
	if err != nil {
		zap.L().Error("GetPostListNew failed", zap.Error(err))
		return nil, err
	}
	return
}
